package com.zbb.online_exam.controller;

import com.baidu.ueditor.ActionEnter;
import com.luhuiguo.fastdfs.domain.StorePath;
import com.luhuiguo.fastdfs.service.FastFileStorageClient;
import com.zbb.online_exam.constant.Method;
import com.zbb.online_exam.dto.JsonResult;
import com.zbb.online_exam.dto.UEUploadResult;
import com.zbb.online_exam.entity.Paper;
import com.zbb.online_exam.exception.NotFoundException;
import com.zbb.online_exam.mapper.PaperMapper;
import com.zbb.online_exam.utils.HttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@Slf4j
@Api(tags = "文件上传和下载功能的相关接口")
public class FileController {
    @Autowired(required = false)
    private HttpServletRequest req;

    @Autowired(required = false)
    private HttpServletResponse res;

    @Autowired
    private HttpUtils httpUtils;

    @Autowired
    private PaperMapper paperMapper;

    /**
     * 这里用的是一个三方对fdfs基于springboot的封装
     */
    @Autowired
    private FastFileStorageClient storageClient;

    /**
     * 下载模板文件时下载后文件显示的名字
     */
    @Value("${stuinfo.temp.name}")
    private String stuInfoTempName;
    /**
     * 通过Nginx访问fdfs时的根路径
     */
    @Value("${fdfs.nginx.path}")
    private String fdfsNginxPath;

    /**
     * 这里的上传就是普通的上传操作【这里主要有别于后面UE中的上传，主要是返回类型不一样，UE中要求特定返回】
     * @param files
     * @return
     */
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    @ApiOperation(value = "普通的上传操作", notes = "权限为管理员才能进行的操作，上传Excel文件")
    public JsonResult upload(@RequestParam("file") MultipartFile[] files) {
        JsonResult result = new JsonResult();
        try {
            if (ArrayUtils.isEmpty(files)) {
                result.setCode(404);
                throw new NotFoundException("请至少选择一个文件进行上传");
            } else {
                List<String> paths = new ArrayList<>();
                for (MultipartFile file : files) {
                    String fileName = file.getOriginalFilename();
                    String extName = FilenameUtils.getExtension(fileName);
                    StorePath storePath = storageClient.uploadFile(file.getBytes(), extName);
                    paths.add(storePath.getFullPath());
                }
                result.setCode(200);
                result.setData(paths);
                // group1/M00/00/00/wKiRZWAdI5CAMEBEAAAiZGFjEGE11.xlsx
                log.info("带分组的路径:"+ Arrays.toString(paths.toArray()));
            }
        } catch (NotFoundException e) {
            e.printStackTrace();
            result = httpUtils.buildFailure(e.getMessage(), Method.POST);
        } catch (Exception e) {
            e.printStackTrace();
            result = httpUtils.build500();
        }
        res.setStatus(res.getStatus());
        return result;
    }

    /**
     * 下载操作
     * @param fileName
     * @throws IOException
     */
    @RequestMapping(value = "download", method = RequestMethod.GET)
    @ApiOperation(value = "普通的下载操作", notes = "权限为老师进行的操作，下载Excel模板")
    public void download(@RequestParam("fileName") String fileName) throws IOException {
        res.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(stuInfoTempName + "." + FilenameUtils.getExtension(fileName), "UTF-8"));
        //TODO:前端传过来的文件名形如：
        // group1/M00/00/00/wKiuZV4_GDeAWcc5ACmbaBLW29o15.xlsx
        int firstSeparatorIndex = fileName.indexOf("/");
        String groupName = fileName.substring(0, firstSeparatorIndex);
        String filePath = fileName.substring(firstSeparatorIndex + 1);
        byte[] bytes = storageClient.downloadFile(groupName, filePath);
        FileCopyUtils.copy(bytes, res.getOutputStream());
    }

    /**
     * 下载试卷
     */
    @RequestMapping(value = "download/{paperId}", method = RequestMethod.GET)
    @ApiOperation(value = "下载试卷", notes = "根据试卷编号下载试卷")
    public void downloadPaper(@PathVariable("paperId") Integer paperId) throws IOException {
        Paper paper = paperMapper.selectById(paperId);
        String fileName = paper.getFullPath();
        res.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode( paper.getFileName(), "UTF-8"));
        int firstSeparatorIndex = fileName.indexOf("/");
        String groupName = fileName.substring(0, firstSeparatorIndex);
        String filePath = fileName.substring(firstSeparatorIndex + 1);
        byte[] bytes = storageClient.downloadFile(groupName, filePath);
        FileCopyUtils.copy(bytes, res.getOutputStream());
    }

    /**
     * Ueditor  GET上传
     */
    @RequestMapping(value = "enterUpload", method = RequestMethod.GET)
    @ApiOperation(value = "加载UE服务器端", notes = "加载UE服务器端相关配置的一个接口路径")
    public String enterUpload(String action, String callback) throws JSONException {
        return new ActionEnter(req, "/").exec();
    }

    /**
     * Ueditor POST上传 多图上传
     */
    @RequestMapping(value = "enterUpload", method = RequestMethod.POST)
    @ApiOperation(value = "多图上传", notes = "严格定义json格式")
    public UEUploadResult enterUpload(@RequestParam("file") MultipartFile file) throws IOException {
        UEUploadResult result=new UEUploadResult();
        String originalFileName=file.getOriginalFilename();
        String type= FilenameUtils.getExtension(originalFileName);
        String savePath= storageClient.uploadFile(file.getBytes(),type ).getFullPath();
        result.setOriginal(originalFileName);
        result.setSize(file.getSize());
        result.setState("SUCCESS");
        result.setTitle(savePath);
        result.setType(type);
        result.setUrl(fdfsNginxPath+"/"+savePath);
        log.info("上传的图片路径:"+result.getUrl());
        return  result;
    }
}
